#define _CRT_SECURE_NO_WARNINGS
#include <foobar2000.h>
#include <libqlyrics.h>

const int MAX_BUFSIZE = 4096;

class play_callback_qlyrics : public play_callback_static {
public:
    virtual void on_playback_starting(play_control::t_track_command p_command, bool p_paused) {};
    virtual void on_playback_new_track(metadb_handle_ptr p_track);
    virtual void on_playback_stop(play_control::t_stop_reason p_reason);
    virtual void on_playback_seek(double p_time);
    virtual void on_playback_pause(bool p_state);
    virtual void on_playback_edited(metadb_handle_ptr p_track);
    virtual void on_playback_dynamic_info(const file_info & info) {};
    virtual void on_playback_dynamic_info_track(const file_info & info) {};
    virtual void on_playback_time(double p_time);
    virtual void on_volume_change(float p_new_val) {};
    void update_cached_info(metadb_handle_ptr p_track);
    virtual unsigned get_flags() {
        return flag_on_playback_new_track | flag_on_playback_seek | flag_on_playback_edited |
            flag_on_playback_pause | flag_on_playback_stop | flag_on_playback_time;
    };
    static const char* wrapString(const char* str) { if (str) return str; else return "";};
    static const char* getTitle() { return m_title; };
    static const char* getAlbum() { return m_album; };
    static const char* getArtist() { return m_artist; };
    static const char* getFilename() { return m_filename; };
    static const char* getTime() {
        static char buf[20];
        sprintf(buf, "%d", m_playbackTime);
        return buf;
    };

protected:
    play_callback_qlyrics();
    ~play_callback_qlyrics();

    static char m_title[MAX_BUFSIZE];
    static char m_album[MAX_BUFSIZE];
    static char m_artist[MAX_BUFSIZE];
    static char m_filename[MAX_BUFSIZE];
    static int m_playbackTime;
};

char play_callback_qlyrics::m_title[MAX_BUFSIZE];
char play_callback_qlyrics::m_album[MAX_BUFSIZE];
char play_callback_qlyrics::m_artist[MAX_BUFSIZE];
char play_callback_qlyrics::m_filename[MAX_BUFSIZE];
int play_callback_qlyrics::m_playbackTime;

play_callback_qlyrics::play_callback_qlyrics() {
    lrcRegisterEvent(RequestTitle, &play_callback_qlyrics::getTitle);
    lrcRegisterEvent(RequestAlbum, &play_callback_qlyrics::getAlbum);
    lrcRegisterEvent(RequestArtist, &play_callback_qlyrics::getArtist);
    //lrcRegisterEvent(RequestLength, &play_callback_qlyrics::getLength);
    lrcRegisterEvent(RequestFilename, &play_callback_qlyrics::getFilename);
    lrcRegisterEvent(RequestTime, &play_callback_qlyrics::getTime);
    m_playbackTime = 0;
    m_title[0] = m_album[0] = m_artist[0] = m_filename[0] = '\0';
    lrcStart();
};

play_callback_qlyrics::~play_callback_qlyrics() {
    // FIXME maybe some checks needed
    lrcStop();
};

void play_callback_qlyrics::on_playback_new_track(metadb_handle_ptr p_track) {
    update_cached_info(p_track);
    m_playbackTime = 0;

    lrcSetStatus(Playing);
    lrcChangeTrack();
};

void play_callback_qlyrics::on_playback_edited(metadb_handle_ptr p_track) {
    update_cached_info(p_track);
};

void play_callback_qlyrics::update_cached_info(metadb_handle_ptr p_track) {
    if (p_track.is_empty())
        return;

    const file_info* p_info;
    p_track->get_info_locked(p_info);

    strcpy(m_title, wrapString(p_info->meta_get("TITLE", 0)));
    strcpy(m_artist, wrapString(p_info->meta_get("ARTIST", 0)));
    strcpy(m_album, wrapString(p_info->meta_get("ALBUM", 0)));
    strcpy(m_filename, p_track->get_path());
    if (strstr(m_filename, "file://") == m_filename) {
        memmove(m_filename, &m_filename[7], strlen(m_filename) - 6);
    };
};

void play_callback_qlyrics::on_playback_stop(play_control::t_stop_reason p_reason) {
    lrcSetStatus(Idle);
};

void play_callback_qlyrics::on_playback_seek(double p_time) {
    m_playbackTime = int(p_time * 1000);
    lrcSetPlaybackTime(m_playbackTime);
};

void play_callback_qlyrics::on_playback_pause(bool p_state) {
    if (p_state) {
        lrcSetStatus(Paused);
    } else {
        metadb_handle_ptr track;
        if (static_api_ptr_t<play_control>()->get_now_playing(track)) {
            lrcSetStatus(Playing);
            track.release();
        } else {
            lrcSetStatus(Idle);
        };        
    };
};

void play_callback_qlyrics::on_playback_time(double p_time) {
    m_playbackTime = int(p_time * 1000);
};

static play_callback_static_factory_t<play_callback_qlyrics> qlyrics_callback_factory;

DECLARE_COMPONENT_VERSION("QLyrics Lyrics Show", "0.2", "QLyrics Lyrics Show plugin for foobar2000.")

